package com.blandware.atleap.webapp.action.core.contentLocale;

import com.blandware.atleap.model.core.ContentLocale;
import com.blandware.atleap.webapp.struts.ContentTilesRequestProcessor;
import com.blandware.atleap.webapp.util.core.LocaleUtil;
import com.blandware.atleap.webapp.util.core.RequestUtil;
import com.blandware.atleap.webapp.util.core.WebappConstants;
import com.blandware.atleap.webapp.util.core.WebappUtil;
import com.blandware.atleap.common.Constants;
import org.apache.commons.validator.GenericValidator;
import org.apache.struts.tiles.ComponentContext;
import org.apache.struts.tiles.ControllerSupport;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


/**
 * <p>Locale list controller. This class is used to grab all locales, construct URLs for switching and put 'em to request
 * </p>
 * <p><a href="LocaleListController.java.html"><i>View Source</i></a></p>
 *
 * @author Sergey Zubtsovskiy <a href="mailto:sergey.zubtsovskiy@blandware.com">&lt;sergey.zubtsovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.19 $ $Date: 2007/04/10 18:38:26 $
 */
public final class LocaleListController extends ControllerSupport {
	//~ Methods ================================================================

	/**
	 * Retrieves all locales and puts them into request
	 *
	 * @param tilesContext   Current tile context
	 * @param request        Current request
	 * @param response       Current response
	 * @param servletContext Current Servlet Context
	 */
	public void execute(ComponentContext tilesContext, HttpServletRequest request, HttpServletResponse response, ServletContext servletContext)
			throws Exception {
		List localesList = LocaleUtil.getInstance(servletContext).getActiveLocales();
		String processedUrl = (String) request.getAttribute(ContentTilesRequestProcessor.PROCESSED_URL);
		if ( processedUrl == null ) {
			processedUrl = WebappUtil.findGlobalForwardConfig("admin", null, request).getPath();
		}

		// detach anchor if any
		String anchor = null;
		int sharp = processedUrl.indexOf("#");
		if ( sharp > 0 ) {
			anchor = processedUrl.substring(sharp + 1);
			processedUrl = processedUrl.substring(0, sharp);
		}

		// detach query string if any
		String queryString = null;
		int questionMark = processedUrl.indexOf("?");
		if ( questionMark > 0 ) {
			queryString = processedUrl.substring(questionMark + 1);
			processedUrl = processedUrl.substring(0, questionMark);
		}

		// remove 'language' and other system parameters if any
		if ( !GenericValidator.isBlankOrNull(queryString) ) {
			Map params = RequestUtil.getRequestParametersFromString(queryString);
			params.remove("language");
            params.remove(WebappConstants.CANONICAL_URI_KEY);
			if ( !params.isEmpty() ) {
				queryString = RequestUtil.createQueryStringFromMap(params, "&", true).toString();
			} else {
				queryString = null;
			}
		}

		Map urls = new HashMap();
		for ( Iterator i = localesList.iterator(); i.hasNext(); ) {
			ContentLocale locale = (ContentLocale) i.next();
			String language = locale.getIdentifier();
			StringBuffer url = new StringBuffer(processedUrl);

			String temp = new String(processedUrl);

			// dot before extension
			int extDot = temp.lastIndexOf(".");
			if ( extDot > 0 ) {

				// save suffix pos for later use
				int suffixPos = extDot;

				// first insert an /rw prefix
				int fromIndex = 0;
				String contextPath = request.getContextPath();
				if ( contextPath == null || contextPath.length() == 0 ) {
					contextPath = "/";
				}

				// we have a choice: processed URL is either absolute or context-relative
				if ( WebappUtil.isAbsoluteURL(processedUrl) ) {
					// look up scheme
					fromIndex = processedUrl.indexOf("://");
					if ( fromIndex < 0 ) {
						fromIndex = processedUrl.indexOf(":") + 1;
					} else {
						fromIndex += 3;
					}
				} else {
					if ( !processedUrl.startsWith(contextPath) ) {
						url = new StringBuffer(contextPath).append(url);
						suffixPos += contextPath.length();
					}
				}

				// insert prefix if it does not exist
				int insertPos;
                if ("/".equals(contextPath)) {
                    insertPos = url.indexOf(contextPath, fromIndex);
                } else {
                    insertPos = url.indexOf(contextPath, fromIndex) + contextPath.length();
                }

                if ( url.indexOf(Constants.LOCALIZED_URI_PREFIX) != insertPos ) {
					url.insert(insertPos, Constants.LOCALIZED_URI_PREFIX);
					suffixPos += Constants.LOCALIZED_URI_PREFIX.length();
				}

				temp = temp.substring(0, extDot);

				// dot before language
				int langDot = temp.lastIndexOf(".");
				if ( langDot == extDot - 3 ) {
					url.replace(langDot, suffixPos, "." + language);
				} else {
					url.insert(suffixPos, "." + language);
				}

			}
			// reattach query string
			if ( !GenericValidator.isBlankOrNull(queryString) ) {
				url.append("?").append(queryString);
			}

			// reattach anchor
			if ( !GenericValidator.isBlankOrNull(anchor) ) {
				url.append("#").append(anchor);
			}

			urls.put(locale, response.encodeURL(url.toString()));
		}

		request.setAttribute(WebappConstants.SWITCH_LOCALE_LINKS_COLLECTION_KEY, urls);
	}
}
